/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JAME is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.core.swing.palette; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.io.IOException; import java.util.TooManyListenersException; import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.plaf.ComponentUI; import net.sf.jame.core.util.Palette; /** * @author Andrea Medeghini */ public class PaletteFieldUI extends ComponentUI { private DropTarget target; private DragSource source; private PaletteFieldController listener; private boolean paintBorder = false; private boolean isTarget = true; private Palette palette; /** * @param c * @return */ public static ComponentUI createUI(final JComponent c) { return new PaletteFieldUI(); } /** * @see java.lang.Object#finalize() */ @Override public void finalize() throws Throwable { listener = null; target = null; source = null; super.finalize(); } /** * @see javax.swing.plaf.ComponentUI#installUI(javax.swing.JComponent) */ @Override public void installUI(final JComponent c) { super.installUI(c); palette = ((PaletteField) c).getPalette(); source = new DragSource(); target = new DropTarget(); listener = new PaletteFieldController((PaletteField) c); c.setToolTipText(createPaletteFieldTooltip(((PaletteField) c).getModel())); installListeners((PaletteField) c); if (source.createDefaultDragGestureRecognizer(c, DnDConstants.ACTION_MOVE, listener) != null) { c.setDropTarget(target); } } /** * @see javax.swing.plaf.ComponentUI#uninstallUI(javax.swing.JComponent) */ @Override public void uninstallUI(final JComponent c) { uninstallListeners((PaletteField) c); LookAndFeel.uninstallBorder(c); c.setDropTarget(null); listener = null; target = null; source = null; super.uninstallUI(c); } private void installListeners(final PaletteField c) { c.addPaletteChangeListener(listener); try { target.addDropTargetListener(listener); } catch (final TooManyListenersException e) { e.printStackTrace(); } } private void uninstallListeners(final PaletteField c) { c.removePaletteChangeListener(listener); target.removeDropTargetListener(listener); } /** * @see javax.swing.plaf.ComponentUI#getPreferredSize(javax.swing.JComponent) */ @Override public Dimension getPreferredSize(final JComponent c) { return new Dimension(256, 64); } /** * @see javax.swing.plaf.ComponentUI#getMinimumSize(javax.swing.JComponent) */ @Override public Dimension getMinimumSize(final JComponent c) { return new Dimension(128, 32); } /** * @see javax.swing.plaf.ComponentUI#getMaximumSize(javax.swing.JComponent) */ @Override public Dimension getMaximumSize(final JComponent c) { return new Dimension(1024, 128); } /** * @see javax.swing.plaf.ComponentUI#paint(java.awt.Graphics, javax.swing.JComponent) */ @Override public void paint(final Graphics g, final JComponent c) { final Insets insets = c.getInsets(); final int w = c.getWidth() - insets.left - insets.right; final int h = c.getHeight() - insets.top - insets.bottom; final Graphics2D g2d = (Graphics2D) g; g.translate(insets.left, insets.top); paintComponent(g2d, c, w, h); } /** * @param g2d * @param c * @param w * @param h */ protected void paintComponent(final Graphics2D g2d, final JComponent c, final int w, final int h) { g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); // g2d.setColor(c.getBackground()); // // g2d.fillRect(0, 0, w, h); final int[] table = palette.renderTable(w); for (int i = 0; i < w; i++) { g2d.setColor(new Color(table[i], true)); g2d.drawLine(i, 0, i, h); } if (paintBorder) { g2d.setColor(c.getForeground()); g2d.drawRect(0, 0, w - 1, h - 1); } } /** * @return */ private String createPaletteFieldTooltip(final PaletteFieldModel model) { return model.getPalette().getName(); } private class PaletteFieldController implements PaletteChangeListener, DropTargetListener, DragGestureListener, DragSourceListener { private final PaletteField field; /** * @param field */ public PaletteFieldController(final PaletteField field) { this.field = field; } /** * @see net.sf.jame.core.swing.palette.PaletteChangeListener#paletteChanged(net.sf.jame.core.swing.palette.PaletteChangeEvent) */ public void paletteChanged(final PaletteChangeEvent e) { palette = ((PaletteFieldModel) e.getSource()).getPalette(); field.setToolTipText(createPaletteFieldTooltip((PaletteFieldModel) e.getSource())); field.repaint(); } /** * @see java.awt.dnd.DropTargetListener#dragEnter(java.awt.dnd.DropTargetDragEvent) */ public void dragEnter(final DropTargetDragEvent e) { if (!field.isDropEnabled()) { e.rejectDrag(); } else if (isTarget) { final DataFlavor[] flavors = e.getCurrentDataFlavors(); boolean accept = false; for (final DataFlavor element : flavors) { if (element.equals(TransferablePalette.PALETTE_FLAVOR)) { accept = true; break; } } if (accept) { e.acceptDrag(DnDConstants.ACTION_MOVE); paintBorder = true; } else { e.rejectDrag(); } } field.repaint(); } /** * @see java.awt.dnd.DropTargetListener#dragOver(java.awt.dnd.DropTargetDragEvent) */ public void dragOver(final DropTargetDragEvent e) { } /** * @see java.awt.dnd.DropTargetListener#dragExit(java.awt.dnd.DropTargetEvent) */ public void dragExit(final DropTargetEvent e) { if (isTarget) { paintBorder = false; } field.repaint(); } /** * @see java.awt.dnd.DropTargetListener#dropActionChanged(java.awt.dnd.DropTargetDragEvent) */ public void dropActionChanged(final DropTargetDragEvent e) { } /** * @see java.awt.dnd.DropTargetListener#drop(java.awt.dnd.DropTargetDropEvent) */ public void drop(final DropTargetDropEvent e) { if (isTarget) { final DataFlavor[] flavors = e.getCurrentDataFlavors(); boolean accept = false; for (final DataFlavor element : flavors) { if (element.equals(TransferablePalette.PALETTE_FLAVOR)) { try { e.acceptDrop(DnDConstants.ACTION_COPY); field.getModel().setPalette((Palette) e.getTransferable().getTransferData(TransferablePalette.PALETTE_FLAVOR), false); accept = true; } catch (final UnsupportedFlavorException x) { x.printStackTrace(); } catch (final IOException x) { x.printStackTrace(); } break; } } if (accept) { e.dropComplete(true); paintBorder = false; field.repaint(); } else { e.rejectDrop(); } } } /** * @see java.awt.dnd.DragGestureListener#dragGestureRecognized(java.awt.dnd.DragGestureEvent) */ public void dragGestureRecognized(final DragGestureEvent e) { if (field.isDragEnabled()) { source.startDrag(e, DragSource.DefaultCopyDrop, new TransferablePalette(field.getModel().getPalette()), this); paintBorder = true; isTarget = false; field.repaint(); } } /** * @see java.awt.dnd.DragSourceListener#dragEnter(java.awt.dnd.DragSourceDragEvent) */ public void dragEnter(final DragSourceDragEvent e) { } /** * @see java.awt.dnd.DragSourceListener#dragOver(java.awt.dnd.DragSourceDragEvent) */ public void dragOver(final DragSourceDragEvent e) { } /** * @see java.awt.dnd.DragSourceListener#dragExit(java.awt.dnd.DragSourceEvent) */ public void dragExit(final DragSourceEvent e) { } /** * @see java.awt.dnd.DragSourceListener#dropActionChanged(java.awt.dnd.DragSourceDragEvent) */ public void dropActionChanged(final DragSourceDragEvent e) { } /** * @see java.awt.dnd.DragSourceListener#dragDropEnd(java.awt.dnd.DragSourceDropEvent) */ public void dragDropEnd(final DragSourceDropEvent e) { paintBorder = false; isTarget = true; field.repaint(); } } }